# -*- coding: utf-8 -*-
import string

__author__ = 'Dante'

import re

def read_template(file):
    tem_file = open(file)
    for i in range(0, 3, 1):
        tem_file.readline()

    line = tem_file.readline()
    content = ""

    while line:
        content += line
        line = tem_file.readline()

    tem_file.close()
    return content

def regular_exp_replace(tplt, new_c, content):
    strinfo = re.compile(tplt)
    return strinfo.sub(new_c, content)

def list_template_operation(list_name, member_struct_name, content):
    content = regular_exp_replace(r"/\*\*LIST-NAME\*\*/", list_name, content)
    content = regular_exp_replace(r"/\*\*STRUCT\*\*/", member_struct_name, content)

    return content

def keyevent_template_operation(keyevent_name, keys_list, keys_interp, content):
    size = len(keys_list)
    tmp_str = ""
    tmp_tplt = ";; -- \"/**key**/\"\t\t\t(Interp. /**key-interpretation**/)"
    for i in range(0, size, 1):
        tx = regular_exp_replace(r"/\*\*key\*\*/", keys_list[i], tmp_tplt)
        tx = regular_exp_replace(r"/\*\*key-interpretation\*\*/", keys_interp[i], tx)
        tmp_str += ("\n" + tx)
    content = (regular_exp_replace("/\\*\\*\\* LOOP1[\n()a-zA-Z/\\*\\-.\"/;? ]*\\*\\*\\*/", tmp_str, content))

    tmp_str = ""
    tmp_tplt = ";;     [(key=? var \"/**key**/\") ...]"
    for i in range(0, size, 1):
        tmp_str += ("\n" + regular_exp_replace(r"/\*\*key\*\*/", keys_list[i], tmp_tplt))
    content = (regular_exp_replace("/\\*\\*\\* LOOP2[\n()\\[\\]a-zA-Z/\\*\\-.\"/;?= ]*\\*\\*\\*/", tmp_str, content))

    content = regular_exp_replace(r"/\*\*KEYEVENT-NAME\*\*/", keyevent_name, content)

    return content

def mouseevent_template_operation(mouseevent_name, interp_list, content,
                                  mouseevent_list = ["button-down", "button-up", "drag", "move", "enter", "leave"]):
    size = len(interp_list)
    tmp_str = ""
    tmp_tplt = ";; -- \"/**mouse**/\"\t\t(Interp. /**mouse-interpretation**/)"
    for i in range(0, size, 1):
        tx = regular_exp_replace(r"/\*\*mouse\*\*/", mouseevent_list[i], tmp_tplt)
        tx = regular_exp_replace(r"/\*\*mouse-interpretation\*\*/", interp_list[i], tx)
        tmp_str += ("\n" + tx)
    content = regular_exp_replace("/\\*\\*\\* LOOP1[\n()a-zA-Z/\\*\\-.\"/;? ]*\\*\\*\\*/", tmp_str, content)

    tmp_str = ""
    tmp_tplt = ";;     [(key=? var \"/**mouse**/\") ...]"
    for i in range(0, size, 1):
        tmp_str += ("\n" + regular_exp_replace(r"/\*\*mouse\*\*/", mouseevent_list[i], tmp_tplt))
    content = regular_exp_replace("/\\*\\*\\* LOOP2[\n()\\[\\]a-zA-Z/\\*\\-.\"/;?= ]*\\*\\*\\*/", tmp_str, content)

    content =regular_exp_replace("/\*\*MOUSE-NAME\*\*/", mouseevent_name, content)
    return content

def struct_template_operation(struct_name, member_list, content):
    tmp_str = ""
    tmp_tplt = "(/**STRUCT**/-/**MEMBER**/ var)"
    for i in member_list:
        tmp_str += ("\n;;     " + regular_exp_replace(r"/\*\*MEMBER\*\*/", i, tmp_tplt))
#    print(tmp_str)
    content = regular_exp_replace("/\\*\\*\\* LOOP[\n()a-zA-Z/\\*\\-; ]*\\*\\*\\*/", tmp_str, content)

    member_list_str = member_list[0]
    for i in range(1, len(member_list), 1):
        member_list_str += (" " + member_list[i])
#    print(member_list_str)
    content = regular_exp_replace(r"/\*\*MEMBER LIST\*\*/", member_list_str, content)

    content = regular_exp_replace(r"/\*\*STRUCT\*\*/", struct_name, content)
    
    return content

def function_template_operation(function_name, arg_list, return_type, test_cases_number, content):
    tmp_str = arg_list[0]
    for i in range(1, len(arg_list), 1):
        tmp_str += (" " + arg_list[i])
    content = regular_exp_replace(r"/\*\*ARG-LIST\*\*/", tmp_str, content)

    tmp_str = ""
    tmp_tplt = "  (check-equal? ... ... \"MSG\")"
    for i in range(0, test_cases_number, 1):
        tmp_str += ("\n" + tmp_tplt)
    content = regular_exp_replace("/\\*\\*\\* LOOP[\n()\\[\\]a-zA-Z/\\*\\-.\"/;?= ]*\\*\\*\\*/", tmp_str, content)

    content = regular_exp_replace(r"/\*\*FUNCTION-NAME\*\*/", function_name, content)
    content = regular_exp_replace(r"/\*\*RETURN-TYPE\*\*/", return_type, content)

    return content

def main_template_operation(provide_list, package_list,
                            struct_tem, list_tem, keyevent_tem,
                            mouseevent_tem, function_tem, content):
    tmp_str = ""
    for i in provide_list:
        tmp_str += "\n  " + i
    content = regular_exp_replace(r"/\*\*PROVIDE-LIST\*\*/", tmp_str, content)

    tmp_str = ""
    tmp_tplt = "(require /**PACKAGE**/)"
    for i in range(0, len(package_list), 1):
        tmp_str += ("\n" + regular_exp_replace(r"/\*\*PACKAGE\*\*/", package_list[i], tmp_tplt))
    content = regular_exp_replace("/\\*\\*\\* LOOP[\n()a-zA-Z/\\*\\- ]*\\*\\*\\*/", tmp_str, content)

    content = regular_exp_replace(r"/1\*\*\*\*\*STRUCT-TEMPLATE\*\*\*\*\*/", struct_tem, content)
    content = regular_exp_replace(r"/2\*\*\*\*\*LIST-TEMPLATE\*\*\*\*\*/", list_tem, content)
    content = regular_exp_replace(r"/3\*\*\*\*\*KEYEVENT-TEMPLATE\*\*\*\*\*/", keyevent_tem, content)
    content = regular_exp_replace(r"/4\*\*\*\*\*MOUSEEVENT-TEMPLATE\*\*\*\*\*/", mouseevent_tem, content)
    content = regular_exp_replace(r"/5\*\*\*\*\*FUNCTION-TEMPLATE\*\*\*\*\*/", function_tem, content)

    return content

def generate_template():
    struct_template     = read_template("../templates/struct.rkt")
    list_template       = read_template("../templates/list.rkt")
    keyevent_template   = read_template("../templates/keyevent.rkt")
    mouseevent_template = read_template("../templates/mouseevent.rkt")
    function_template   = read_template("../templates/function.rkt")
    main_template       = read_template("../templates/template.rkt")

    member_list = ["pos-x", "pos-y"]
    keys_list = ["1", "2", "3"]
    keys_interp = ["fuckTA1", "fuckTA2", "fuckTA3"]
    tem1 = struct_template_operation("Test", member_list, struct_template)
    tem2 = list_template_operation("ListOf<ball>", "ball", list_template)
    tem3 = keyevent_template_operation("myKey", keys_list, keys_interp, keyevent_template)
    tem4 = mouseevent_template_operation("x", keys_interp, mouseevent_template)
    tem5 = function_template_operation("funcName", keys_interp, "NULL", 5, function_template)
    print main_template_operation(keys_interp, keys_interp, tem1, tem2, tem3, tem4, tem5, main_template)

def generate_function_template(setting_file):
    function_template = read_template("../templates/function.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    number = string.atoi(line)

    tmp_str = ""

    for i in range(0, number, 1):
        line = setting.readline().strip('\n').strip('\r')
        if line[0] == '/' and line[1] == "/":
            continue
        tmp = line.split('|')
        name = tmp[0]
        return_type = tmp[1]
        test_cases_number = string.atoi(tmp[2])
        del tmp[2]
        del tmp[1]
        del tmp[0]
        tmp_str += (function_template_operation(name, tmp, return_type, test_cases_number, function_template) + "\n\n")

    return tmp_str

def generate_mouseevent_template(setting_file):
    mouseevent_template = read_template("../templates/mouseevent.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    number = string.atoi(line)
    name = setting.readline().strip('\n').strip('\r')

    mouseevent_list = []
    mouseevent_interp = []

    for i in range(0, number, 1):
        line = setting.readline().strip('\n').strip('\r')
        if line[0] == '/' and line[1] == "/":
            continue
        tmp = line.split('|')
        mouseevent_list.append(tmp[0])
        mouseevent_interp.append(tmp[1])

    return mouseevent_template_operation(name, mouseevent_interp, mouseevent_template, mouseevent_list)

def generate_keyevent_template(setting_file):
    keyevent_template = read_template("../templates/keyevent.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    number = string.atoi(line)
    name = setting.readline().strip('\n').strip('\r')

    keys_list = []
    keys_interp = []

    for i in range(0, number, 1):
        line = setting.readline().strip('\n').strip('\r')
        if line[0] == '/' and line[1] == "/":
            continue
        tmp = line.split('|')
        keys_list.append(repr(tmp[0]).replace("'", ""))
        keys_interp.append(repr(tmp[1]).replace("'", ""))

    return keyevent_template_operation(name, keys_list, keys_interp, keyevent_template)

def generate_struct_template(setting_file):
    struct_template = read_template("../templates/struct.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    number = string.atoi(line)

    struct_tem = ""

    for i in range(0, number, 1):
        line = setting.readline().strip('\n').strip('\r')
        if line[0] == '/' and line[1] == "/":
            continue
        tmp = line.split('|')
        name = tmp[0]
        del tmp[0]
        struct_tem += (struct_template_operation(name, tmp, struct_template) + "\n\n")

    return struct_tem

def generate_list_template(setting_file):
    list_template = read_template("../templates/list.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    number = string.atoi(line)

    list_tem = ""

    for i in range(0, number, 1):
        line = setting.readline().strip('\n').strip('\r')
        if line[0] == '/' and line[1] == "/":
            continue
        tmp = line.split('|')
        name = tmp[0]
        del tmp[0]
        list_tem += (list_template_operation(name, tmp[0], list_template) + "\n\n")

    return list_tem

def generate_main_template(setting_file, struct_tem, list_tem, keyevent_tem, mouseevent_tem, function_tem):
    main_template = read_template("../templates/template.rkt")
    setting = open(setting_file)
    line = setting.readline().strip('\n').strip('\r')
    line = setting.readline().strip('\n').strip('\r') # again
    provide_list = line.split('|')
    line = setting.readline().strip('\n').strip('\r')
    line = setting.readline().strip('\n').strip('\r') # again
    require_list = line.split('|')

    return main_template_operation(provide_list, require_list, struct_tem,
                                   list_tem, keyevent_tem, mouseevent_tem,
                                   function_tem, main_template)

def main():
    struct_tem = generate_struct_template("../settings/struct-setting.txt")
    list_tem = generate_list_template("../settings/list-setting.txt")
    keyevent_tem = generate_keyevent_template("../settings/keyevent-setting.txt")
    mouseevent_tem = generate_mouseevent_template("../settings/mouseevent-setting.txt")
    function_tem = generate_function_template("../settings/function-setting.txt")

    main_tem = generate_main_template("../settings/main-setting.txt",
                                  struct_tem, list_tem, keyevent_tem,
                                  mouseevent_tem, function_tem)

    f = open("MyTemplate.rkt", "w")
    header = ";; The first three lines of this file were inserted by DrRacket. They record metadata\n"
    header += ";; about the language level of this file in a form that our tools can easily process.\n"
    header += "#reader(lib \"htdp-intermediate-reader.ss\" \"lang\")((modname mouseevent) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))"
    f.write(header + main_tem)
    f.close()

if __name__ == '__main__':
    main()